package com.dingwen.treasure.manage.service.impl;

import com.dingwen.treasure.base.constant.RabbitmqConstant;
import com.dingwen.treasure.manage.service.SmsService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import java.io.IOException;

/**
 * 　SmsServiceImpl
 * <pre>
 *     1. {@code @RabbitListener} 可在类上使用也可在方法上使用
 *     2. {@code @RabbitHandler} 配合 {@code @RabbitListener} 在方法上面使用，按照指定消息类型进行转换
 * </pre>
 * <p>@RabbitListener</p>
 * <ol>
 *     <li>queues： 指定队列名称</li>
 *     <li>concurrency： 并发控制，最多同时四个线程</li>
 *     <li>ackMode： 开启手动应答模式</li>
 * </ol>
 * <p>单个队列只有一个消费者： 保证消息进行顺序消费</p>
 * 　@author dingwen
 * 　@date 2022/6/5
 */
@Service
@Slf4j
@RabbitListener(queues = {RabbitmqConstant.QUEUE_SMS}, concurrency = "4", ackMode = "MANUAL")
public class SmsServiceImpl implements SmsService {
    /**
     * 发送
     *
     * @param messages 信息主体
     * @param message  消息
     * @param channel  频道
     */
    @RabbitHandler
    @Override
    public void send(Message messages, String message, Channel channel) throws IOException {
        // 消息ID
        long deliveryTag = messages.getMessageProperties().getDeliveryTag();

        log.info("消息消费，消息内容：{}", message);

        // 确认消费消息，单条确定
        channel.basicAck(deliveryTag, Boolean.FALSE);
        //TODO 借助三方存储消息ID实现消息状态维护，确保不会重复消费

        // 确认消费失败，单条确定，重回队列
        //channel.basicNack(deliveryTag, Boolean.FALSE, Boolean.TRUE);
    }
}
